package com.jinzecloud.reportapproval.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.jinzecloud.reportapproval.bean.*;
import com.jinzecloud.reportapproval.dto.AdminDto;
import com.jinzecloud.reportapproval.dto.AuditParam;
import com.jinzecloud.reportapproval.dto.DataStagingParam;
import com.jinzecloud.reportapproval.enums.AuditRoleEnums;
import com.jinzecloud.reportapproval.enums.StateEnum;
import com.jinzecloud.reportapproval.enums.TableEnums;
import com.jinzecloud.reportapproval.service.SampleDetailsService;
import com.jinzecloud.reportapproval.service.SampleSheetWorkplaceDetailService;
import com.jinzecloud.reportapproval.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.jinzecloud.reportapproval.mapper.SampleSheetMapper;
import com.jinzecloud.reportapproval.service.SampleSheetService;

import javax.servlet.http.HttpServletRequest;


@Service("sampleSheetService")
@RequiredArgsConstructor
public class SampleSheetServiceImpl extends ServiceImpl<SampleSheetMapper, SampleSheet> implements SampleSheetService {

    private final SampleDetailsService sampleDetailsService;
    private final SampleSheetWorkplaceDetailService sampleSheetWorkplaceDetailService;
    private final FileUploadUtil fileUploadUtil;
    private final HttpServletRequest request;
    @Override
    public IPage<SampleSheet> auditList(DataStagingParam param) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LambdaQueryWrapper<SampleSheet> queryWrapper = new LambdaQueryWrapper<>();
        List<AdminDto> adminDto = AuditUtil.getAdminDto(authentication.getName());
        Set<Integer> roleSet = adminDto.stream().map(a -> StateEnum.getStateEnumByAuditRole(a.getRoleCode()).getState()).collect(Collectors.toSet());
        roleSet.remove(StateEnum.UN_SUBMIT.getState());
        queryWrapper.in(SampleSheet::getState, AuditUtil.getCurrentStateIndex(TableEnums.SAMPLE_SHEET.getTableName(), roleSet));
        queryWrapper.and(w -> w.like(SampleSheet::getPrototypeTrademark, param.getSearchKey()).or()
                .like(StrUtil.isNotEmpty(param.getSearchKey()), SampleSheet::getProjectCode, param.getSearchKey()));
        return page(new Page<>(param.getPageNo(), param.getPageSize()), queryWrapper);
    }

    @Override
    public R audit(AuditParam auditParam) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        List<AdminDto> adminDos = AuditUtil.getAdminDto(authentication.getName());
        if (CollectionUtil.isEmpty(adminDos)) return R.error("您没有审核权限！");
        SampleSheet sampleSheet = this.getById(auditParam.getId());
        int state = sampleSheet.getState();
        if (!auditParam.isState()) {
            updateById(sampleSheet.setState(StateEnum.APPROVAL_NOT_PASS.getState())
                    .setAuditOpinion(auditParam.getAuditOpinion())
                    .setAuditDate(DateUtil.date()));
            return R.ok();
        }
        StateEnum currentAuditState = AuditUtil.getStateText(TableEnums.SAMPLE_SHEET.getTableName(), state);
        Integer nextAuditStateIndex = AuditUtil.getNextAuditState(TableEnums.SAMPLE_SHEET.getTableName(), state, adminDos.stream().map(AdminDto::getRoleCode).toList());        AdminDto adminDto = adminDos.stream().filter(a -> StrUtil.equals(a.getRoleCode(), currentAuditState.getAuditRole()))
                .findFirst().orElse(null);
        if (adminDto == null || nextAuditStateIndex == null) return R.error("您没有审核权限！");
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.SAMPLER.getCode())) sampleSheet.setSampler(adminDto.getAdSignature());
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.DEPARTMENT_HEAD.getCode())) sampleSheet.setDepartmentHead(adminDto.getAdSignature());
        sampleSheet.setState(nextAuditStateIndex)
                .setAuditOpinion(auditParam.getAuditOpinion())
                .setAuditDate(DateUtil.date());
        updateById(sampleSheet);
        return R.ok();
    }

    public String fileDownload(SampleSheet sampleSheet, HttpServletRequest request) {
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(sampleSheet, JSONWriter.Feature.NullAsDefaultValue.ordinal()));
        data.put("sampleDetailsList", sampleDetailsService.list(new LambdaQueryWrapper<SampleDetails>().eq(SampleDetails::getSampleSheetId, sampleSheet.getId())));
        data.put("sampleSheetWorkplaceDetailList", sampleSheetWorkplaceDetailService.list(new LambdaQueryWrapper<SampleSheetWorkplaceDetail>().eq(SampleSheetWorkplaceDetail::getSampleSheetId, sampleSheet.getId())));
//        data.put("sampler", StrUtil.isNotEmpty(sampleSheet.getSampler()) ? Pictures.ofUrl(sampleSheet.getSampler()).size(30, 10).create() : null);
//        data.put("departmentHead", StrUtil.isNotEmpty(sampleSheet.getDepartmentHead()) ? Pictures.ofUrl(sampleSheet.getDepartmentHead()).size(30, 10).create() : null);
        File tempFile = WordUtil.getWordFile("template/sampleSheet.docx", data, Configure.builder()
                .bind("sampleDetailsList", policy)
                .bind("sampleSheetWorkplaceDetailList", policy)
                .useSpringEL(true)
        );
        if (tempFile == null) return null;
        String fileName = "抽样单";
        String uploadDirectory = fileUploadUtil.getUploadFilePath("temp");
        String filePath = uploadDirectory + sampleSheet.getPrototypeTrademark() + fileName;
        String savePath = RequestUtils.getBasePath(request) + "upload/temp/" + sampleSheet.getPrototypeTrademark() +fileName;
        FileUtil.copy(tempFile, new File(filePath + ".docx"), true);
        PDFUtil.WordToPdf(tempFile, new File(filePath + ".pdf"));
        this.update(new LambdaUpdateWrapper<SampleSheet>().set(SampleSheet::getWordPath, savePath + ".docx").set(SampleSheet::getPdfPath, savePath + ".pdf").eq(SampleSheet::getId, sampleSheet.getId()));
        return RequestUtils.getBasePath(request) + "upload/temp/" + sampleSheet.getPrototypeTrademark() + fileName + ".pdf";
    }

    public String fileDownloadWord(SampleSheet sampleSheet, HttpServletRequest request) {
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(sampleSheet, JSONWriter.Feature.NullAsDefaultValue.ordinal()));
        data.put("sampleDetailsList", sampleDetailsService.list(new LambdaQueryWrapper<SampleDetails>().eq(SampleDetails::getSampleSheetId, sampleSheet.getId())));
        data.put("sampleSheetWorkplaceDetailList", sampleSheetWorkplaceDetailService.list(new LambdaQueryWrapper<SampleSheetWorkplaceDetail>().eq(SampleSheetWorkplaceDetail::getSampleSheetId, sampleSheet.getId())));
//        data.put("sampler", StrUtil.isNotEmpty(sampleSheet.getSampler()) ? Pictures.ofUrl(sampleSheet.getSampler()).size(30, 10).create() : null);
//        data.put("departmentHead", StrUtil.isNotEmpty(sampleSheet.getDepartmentHead()) ? Pictures.ofUrl(sampleSheet.getDepartmentHead()).size(30, 10).create() : null);
        File tempFile = WordUtil.getWordFile("template/sampleSheet.docx", data, Configure.builder()
                .bind("sampleDetailsList", policy)
                .bind("sampleSheetWorkplaceDetailList", policy)
                .useSpringEL(true)
        );
        if (tempFile == null) return null;
        String fileName = "抽样单";
        String uploadDirectory = fileUploadUtil.getUploadFilePath("temp");
        String filePath = uploadDirectory + sampleSheet.getPrototypeTrademark() + fileName;
        String savePath = RequestUtils.getBasePath(request) + "upload/temp/" + sampleSheet.getPrototypeTrademark() +fileName;
        FileUtil.copy(tempFile, new File(filePath + ".docx"), true);
        PDFUtil.WordToPdf(tempFile, new File(filePath + ".pdf"));
        this.update(new LambdaUpdateWrapper<SampleSheet>().set(SampleSheet::getWordPath, savePath + ".docx").set(SampleSheet::getPdfPath, savePath + ".pdf").eq(SampleSheet::getId, sampleSheet.getId()));
        return RequestUtils.getBasePath(request) + "upload/temp/" + sampleSheet.getPrototypeTrademark() + fileName + ".docx";
    }

    @Override
    public String getReportFilePath(String id, HttpServletRequest request) {
        SampleSheet sampleSheet = getById(id);
//        if (StrUtil.isEmpty(sampleSheet.getWordPath()) || StrUtil.isEmpty(sampleSheet.getPdfPath())){
            return fileDownload(sampleSheet, request);
//        }
//        return sampleSheet.getPdfPath();
    }

    @Override
    public String viewPdf(Integer id) {
        SampleSheet sampleSheet = getById(id);
        String s = fileDownload(sampleSheet, request);
        return s;
    }

    @Override
    public R saveSampleSheet(SampleSheet sampleSheet) {
        QueryWrapper<SampleSheet> sampleSheetQueryWrapper = new QueryWrapper<>();
        sampleSheetQueryWrapper.eq("project_code", sampleSheet.getProjectCode());
        List<SampleSheet> list = list(sampleSheetQueryWrapper);
        if (list.size() >= 1) return R.error("编号："+sampleSheet.getProjectCode()+"已存在，请勿重复添加！");
        save(sampleSheet);
        return R.ok();
    }

    @Override
    public List<SampleDetails> getProductNumber(String projectNumber) {
        QueryWrapper<SampleSheet> sampleSheetQueryWrapper = new QueryWrapper<>();
        sampleSheetQueryWrapper.eq("project_code", projectNumber);
        SampleSheet sampleSheet = this.getOne(sampleSheetQueryWrapper);
        List<SampleDetails> details = sampleDetailsService.getBySheeltId(sampleSheet.getId());
        return details;
    }

    @Override
    public String viewWord(Integer id) {
        SampleSheet sampleSheet = getById(id);
        String s = fileDownloadWord(sampleSheet, request);
        return s;
    }

}